
//砍价活动
package shopping

import (
    "fmt"
    "time"
	"errors"
	"strings"
	"dhfshop/models"
	"dhfshop/models/consts"
	"github.com/astaxie/beego/orm"
)

// 砍价活动规则表
type BargainRule struct {
    BargainRuleId    int64     `orm:"column(bargain_rule_id);pk;auto" json:"bargain_rule_id" form:"bargain_rule_id"` //自增ID
    PartnerId        int64     `orm:"column(partner_id)" json:"partner_id" form:"partner_id"`      //商家ID
    StoreId          int64     `orm:"column(store_id)" json:"store_id" form:"store_id"`
	ItemId           int64     `orm:"column(item_id);index" json:"item_id,string" form:"-"`                      //商品ID
	ItemIdStr        string   `orm:"-" json:"-" form:"item_id"`
	SkuId            int64     `orm:"column(sku_id);unique" json:"sku_id,string" form:"-"`                  //规格ID
    SkuIdStr         string   `orm:"-" json:"-" form:"sku_id"`
	Title            string    `orm:"column(title);size(32);null" json:"title" form:"title"`       //标题
	NeedBargainTimes int       `orm:"column(need_bargain_times)" json:"need_bargain_times" form:"need_bargain_times"`                  //需要拉人砍的次数
	NeedCutOffFee    float32   `orm:"column(need_cut_off_fee);digits(12);decimals(2)" json:"need_cut_off_fee" form:"need_cut_off_fee"` //需要砍掉金额
	MinBargainTimes  int       `orm:"column(min_bargain_times);default(0)" json:"min_bargain_times" form:"min_bargain_times"`  //使用优惠的最低砍价次数
	StartTime        time.Time `orm:"column(start_time);type(datetime);null" json:"-" form:"-"`   //开始时间
	EndTime          time.Time `orm:"column(end_time);type(datetime);null" json:"-" form:"-"`     //结束时间
	CutWay           int       `orm:"column(cut_way)" json:"cut_way" form:"cut_way"`              //砍价额度方式： 1 均价 2 随机
	//非数据库字段
	StartTimeStr     string    `orm:"-" json:"start_time" form:"start_time"`                      //输入输出
	EndTimeStr       string    `orm:"-" json:"end_time" form:"end_time"`                          //输入输出
}

//砍价活动表
type BargainActivity struct {
    BargainActivityId int64   `orm:"column(bargain_activity_id);pk;auto" json:"bargain_activity_id" form:"bargain_activity_id"`
	PartnerId         int64   `orm:"column(partner_id)" json:"partner_id" form:"-"`            //商家ID
	BargainRuleId     int64   `orm:"column(bargain_rule_id)" json:"bargain_rule_id" form:"bargain_rule_id"`
	TotalBargainTimes int     `orm:"column(total_bargain_times)" json:"total_bargain_times" form:"-"`  //当前总共拉人砍价的次数
	TotalCutOffFee    float32 `orm:"column(total_cut_off_fee);digits(12);decimals(2)" json:"total_cut_off_fee" form:"-"` //当前总共砍掉的金额
    OpenId            string  `orm:"column(open_id);size(128)" json:"open_id" form:"open_id"` //顾客微信公众号标记id
	IsUsed            int     `orm:"column(is_used);default(0)" json:"is_used" form:"-"`  //是否已经使用过,0没使用，1已使用(订单创建时候需要校验)
	// 非数据库字段
	FormId            string  `orm:"-" json:"-" form:"form_id"`         //为了发送通知，保存的form_id     
}

//砍价活动详情表
type BargainActivityDetails struct {
    BargainDetailId   int64     `orm:"column(bargain_detail_id);pk;auto" json:"bargain_detail_id" form:"bargain_detail_id"`
	PartnerId         int64     `orm:"column(partner_id)" json:"partner_id" form:"partner_id"`                            //商家ID
	BargainRuleId     int64     `orm:"column(bargain_rule_id)" json:"bargain_rule_id" form:"bargain_rule_id"`             //
	BargainActivityId int64     `orm:"column(bargain_activity_id)" json:"bargain_activity_id" form:"bargain_activity_id"` //
	CutOffFee         float32   `orm:"column(cut_off_fee);digits(12);decimals(2)" json:"cut_off_fee" form:"cut_off_fee"`  //本次砍掉的金额
	CutOffTime        time.Time `orm:"auto_now_add;column(cut_off_time);type(datetime);null" json:"-" form:"-"`           //砍价时间
    OpenId            string    `orm:"column(open_id);size(128)" json:"open_id" form:"open_id"`                                     //砍客微信公众号标记id
	//非数据库字段
	CutOffTimeStr     string    `orm:"-" json:"cut_off_time" form:"cut_off_time"`                      //输入输出
}

func init() {
    orm.RegisterModel(new(BargainRule),new(BargainActivity),new(BargainActivityDetails))   
}

func (u *BargainActivity) TableUnique() [][]string {
	return [][]string{
		[]string{"BargainRuleId", "OpenId"},
	}
}

func (u *BargainActivityDetails) TableUnique() [][]string {
	return [][]string{
		[]string{"BargainActivityId", "OpenId"},
	}
}

/*****砍价活动规则表操作API**************/
func AddBargainRule(m *BargainRule) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}
func GetBargainRuleById(id int64) (v *BargainRule, err error) {
	o := models.GetDefaultDB()
	v = &BargainRule{BargainRuleId: id}
	if err = o.Read(v); err == nil {
		v.StartTimeStr = v.StartTime.Format(consts.DATETIME_FORMAT)
		v.EndTimeStr = v.EndTime.Format(consts.DATETIME_FORMAT)
		return v, nil
	}
	return nil, err
}
func GetAllBargainRules(query map[string]string,fields []string,order_by map[string]string,offset,limit int)([]*BargainRule,int64,error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(BargainRule))
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	cnt, err := qs.Count()
	// order by:
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	qs = qs.OrderBy(sortFields...)
	var lists []*BargainRule
	if _, err := qs.Limit(limit, offset).All(&lists, fields...); err == nil {
	    for _, temp := range lists {
			temp.StartTimeStr = temp.StartTime.Format(consts.DATETIME_FORMAT)
			temp.EndTimeStr = temp.EndTime.Format(consts.DATETIME_FORMAT)
	    }
		return lists, cnt, nil
	}
	return nil, 0, err
}
func UpdateBargainRuleById(m *BargainRule, k ...string) (err error) {
	o := models.GetDefaultDB()
	v := BargainRule{BargainRuleId: m.BargainRuleId, PartnerId: m.PartnerId}
	if err = o.Read(&v, "BargainRuleId", "PartnerId"); err != nil {
		return err
	}else{
	    if _, err = o.Update(m, k...); err != nil {
		   return err
		}
	}
	return nil
}
func DeleteBargainRule(partnerId int64, id int64) (err error) {
	o := models.GetDefaultDB()
	v := BargainRule{BargainRuleId: id, PartnerId: partnerId}
	if err = o.Read(&v, "BargainRuleId", "PartnerId"); err == nil {
		if _, err = o.Delete(&v); err == nil {
			return nil
		}
	}
	return
}

func GetTimeValidBargainRules(itemId int64) (bargainRules []*BargainRule, err error) {
	curUtcTime := time.Now().UTC()
	bargainRules = []*BargainRule{}
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(BargainRule)).Filter("item_id", itemId)
	qs = qs.Filter("start_time__lt", curUtcTime)
	qs = qs.Filter("end_time__gt", curUtcTime)
	if _, err = qs.All(&bargainRules); err == nil {
	    for _, rule := range bargainRules {
			rule.StartTimeStr = rule.StartTime.Format(consts.DATETIME_FORMAT)
			rule.EndTimeStr = rule.EndTime.Format(consts.DATETIME_FORMAT)
		}
	}
	return
}

/*****砍价活动表操作API**************/
func AddBargainActivity(m *BargainActivity) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}
func GetBargainActivityById(id int64) (v *BargainActivity, err error) {
	o := models.GetDefaultDB()
	v = &BargainActivity{BargainActivityId: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}
func GetAllBargainActivitys(query map[string]string,fields []string,order_by map[string]string,offset,limit int)([]*BargainActivity,int64,error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(BargainActivity))
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	cnt, err := qs.Count()
	// order by:
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	qs = qs.OrderBy(sortFields...)
	var lists []*BargainActivity
	if _, err := qs.Limit(limit, offset).All(&lists, fields...); err == nil {
		return lists, cnt, nil
	}
	return nil, 0, err
}
func UpdateBargainActivityById(m *BargainActivity, k ...string) (err error) {
	o := models.GetDefaultDB()
	v := BargainActivity{BargainActivityId: m.BargainActivityId}
	if err = o.Read(&v); err != nil {
		return err
	}else{
	    if _, err = o.Update(m, k...); err != nil {
		   return err
		}
	}
	return nil
}
func DeleteBargainActivity(id int64) (err error) {
	o := models.GetDefaultDB()
	v := BargainActivity{BargainActivityId: id}
	if err = o.Read(&v); err == nil {
		if _, err = o.Delete(&v); err == nil {
			return nil
		}
	}
	return
}

/*****砍价活动详情表操作API**************/

func AddBargainActivityDetails(m *BargainActivityDetails) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}
func GetBargainActivityDetailsById(id int64) (v *BargainActivityDetails, err error) {
	o := models.GetDefaultDB()
	v = &BargainActivityDetails{BargainDetailId: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}
func GetAllBargainActivityDetails(query map[string]string,fields []string,order_by map[string]string,offset,limit int)([]*BargainActivityDetails,int64,error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(BargainActivityDetails))
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	cnt, err := qs.Count()
	// order by:
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	qs = qs.OrderBy(sortFields...)
	var lists []*BargainActivityDetails
	if _, err := qs.Limit(limit, offset).All(&lists, fields...); err == nil {
	    for _, temp := range lists {
			temp.CutOffTimeStr = temp.CutOffTime.Format(consts.DATETIME_FORMAT)
	    }
		return lists, cnt, nil
	}
	return nil, 0, err
}
func UpdateBargainActivityDetailsById(m *BargainActivityDetails, k ...string) (err error) {
	o := models.GetDefaultDB()
	v := BargainActivityDetails{BargainDetailId: m.BargainDetailId}
	if err = o.Read(&v); err != nil {
		return err
	}else{
	    if _, err = o.Update(m, k...); err != nil {
		   return err
		}
	}
	return nil
}
func DeleteBargainActivityDetails(id int64) (err error) {
	o := models.GetDefaultDB()
	v := BargainActivityDetails{BargainDetailId: id}
	if err = o.Read(&v); err == nil {
		if _, err = o.Delete(&v); err == nil {
			return nil
		}
	}
	return
}

/****************订单优惠计算************************/
func GetBargainDiscountFee(bargainActivityId int64) (float32, error){
	bargainActivity, err := GetBargainActivityById(bargainActivityId)
	if err != nil {
	    return 0, errors.New("bargain activity is null")
	}
	return bargainActivity.TotalCutOffFee, nil
}

func SumBargainActivitys(partnerId, bargainRuleId int64) (totalActivitys, totalTimes int, totalFees float32, err error) {
    o := models.GetDefaultDB()
	sql := fmt.Sprintf(`select count(*) as total_activitys,sum(total_bargain_times) as total_times,sum(total_cut_off_fee) as total_fees from bargain_activity where partner_id=%d and bargain_rule_id=%d`, partnerId, bargainRuleId)
	err = o.Raw(sql).QueryRow(&totalActivitys, &totalTimes, &totalFees)
	return
}
